/**
 * 验证给定的字符串是否可以解释为十进制数字。
 * <p>
 * 例如:
 * <p>
 * "0" => true
 * " 0.1 " => true
 * "abc" => false
 * "1 a" => false
 * "2e10" => true
 * " -90e3   " => true
 * " 1e" => false
 * "e3" => false
 * " 6e-1" => true
 * " 99e2.5 " => false
 * "53.5e93" => true
 * " --6 " => false
 * "-+3" => false
 * "95a54e53" => false
 * <p>
 * 说明: 我们有意将问题陈述地比较模糊。在实现代码之前，你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表：
 * <p>
 * 数字 0-9
 * 指数 - "e"
 * 正/负号 - "+"/"-"
 * 小数点 - "."
 * 当然，在输入中，这些字符的上下文也很重要。
 */
class Solution {

    public static void main(String[] args) {
        System.out.println(isNumber("9"));
        System.out.println(isNumber("   0.1 "));
        System.out.println(isNumber("2e10"));
        System.out.println(isNumber(" -90e3   "));
        System.out.println(isNumber(" 6e-1"));
        System.out.println(isNumber("53.5e93"));
        System.out.println(isNumber(".1"));
        System.out.println(isNumber("1."));
        System.out.println(isNumber("+.1"));
        System.out.println(isNumber("-1."));
        System.out.println(isNumber("46.e3"));

        System.out.println("-----------------");


        System.out.println(isNumber("+."));
        System.out.println(isNumber("1 a"));
        System.out.println(isNumber(" 1e"));
        System.out.println(isNumber("e3"));
        System.out.println(isNumber(" 99e2.5 "));
        System.out.println(isNumber(" --6 "));
        System.out.println(isNumber("-+3"));
        System.out.println(isNumber("95a54e53"));
    }

    public static boolean isNumber(String s) {
        s = s.trim();
        if (s.length() == 1) {
            char c = s.charAt(0);
            return c >= '0' && c <= '9';
        } else if (s.length() > 1) {
            char c = s.charAt(0);
            if (c >= '0' && c <= '9') {
                return afterNum(s, 1, false);
            } else if (c == '+' || c == '-') {
                c = s.charAt(1);
                // 后面可以只能是数字
                if ((c >= '0' && c <= '9')) {
                    return s.length() == 2 || afterNum(s, 2, false);
                } else if (c == '.') {
                    if (s.length() == 2) {
                        return false;
                    }
                    c = s.charAt(2);
                    if (c >= '0' && c <= '9') {
                        return afterNum(s, 3, true);
                    }
                }
            } else if (c == '.') {
                c = s.charAt(1);
                // 后面可以只能是数字
                if (c >= '0' && c <= '9') {
                    return s.length() == 2 || afterNum(s, 2, true);
                }
            }
        }
        return false;
    }

    /**
     * 前面已经有数字了，从数字开始判断
     *
     * @param s
     * @param x
     * @return
     */
    private static boolean afterNum(String s, int x, boolean used) {
        char c = ' ';
        for (int i = x; i < s.length(); i++) {
            c = s.charAt(i);
            // 后面可以是数字或者.或者e
            if (c >= '0' && c <= '9') {
            } else if (!used && c == '.') {
                // 后面必须是数字，数字之后接e
                if (++i == s.length()) {
                    return true;
                }
                c = s.charAt(i);
                if ((c >= '0' && c <= '9') || c <= 'e') {
                    return afterNum(s, i, true);
                } else {
                    return false;
                }
            } else if (c == 'e') {
                // 后面允许+-数字
                return afterE(s, i + 1);
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 在e之后，允许+-数字
     *
     * @param s
     * @param x
     * @return
     */
    private static boolean afterE(String s, int x) {
        // 如果已经结束了，则不满足
        if (x == s.length()) {
            return false;
        }
        // 如果存在+-则去掉
        char c = s.charAt(x);
        if (c == '+' || c == '-') {
            x += 1;
        }
        // 判断后面必须是有数字且全是数字
        return leftNum(s, x);
    }

    /**
     * 后面必须是有数字且全是数字
     *
     * @param s
     * @param x
     * @return
     */
    private static boolean leftNum(String s, int x) {
        // 如果已经结束了，则不满足
        if (x >= s.length()) {
            return false;
        }
        for (int i = x; i < s.length(); i++) {
            if (s.charAt(i) < '0' || s.charAt(i) > '9') {
                return false;
            }
        }
        return true;
    }

}